package com.silverhaze.diamond.client.ui.dialogs;

import com.silverhaze.commons.db.datasource.ObjectEntity;
import com.silverhaze.commons.helpers.CommonUIHelper;
import com.silverhaze.commons.ui.layout.SpringUtilities;
import com.silverhaze.commons.ui.simpledatepicker.SimpleDatePicker;
import com.silverhaze.diamond.client.common.AuroraConstants;
import com.silverhaze.diamond.client.data.dao.DAOLocator;
import com.silverhaze.diamond.client.settings.SettingsStorage;
import com.silverhaze.diamond.client.ui.components.StringAutoCompleteComboBox;
import com.silverhaze.diamond.client.ui.table.CountedDetailTable;
import com.silverhaze.diamond.client.ui.table.model.CountedDetailsTableModel;
import com.silverhaze.diamond.common.entity.BrokenDetail;
import com.silverhaze.diamond.common.entity.Customer;
import com.silverhaze.diamond.common.entity.Service;
import com.silverhaze.diamond.common.entity.UsedDetail;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.*;
import java.util.List;

/**
 * Created by Ivan Babanin (11:54:25 01.06.2008)
 * This part of code is strictly confidential.
 * © Magnificent Software Inc.
 */
public class ServiceDialog extends AbstractDialog {

    private static final int FIELD_SIZE = 15;

    private boolean edit;
    private Service service;
    private DialogType dialogType;
    private Customer selectedCustomer;

    // Basic fields
    private JRadioButton diagRadioButton;
    private JRadioButton repairRadioButton;
    private StringAutoCompleteComboBox techName;
    private StringAutoCompleteComboBox techModelName;
    private StringAutoCompleteComboBox modelName;
    private StringAutoCompleteComboBox stampState;
    private JTextField serialNumber;
    private SimpleDatePicker dateOfProduce;
    private JTextField guarantyNumber;
    private StringAutoCompleteComboBox completeness;
    private JTextArea customerDefect;
    private JTextArea masterDefect;
    private JButton customerSelectorBtn;

    // Service complete
    private JRadioButton guarantyRadioButton;
    private JRadioButton payedRadioButton;
    private JRadioButton modernRadioButton;
    private JRadioButton refuseRadioButton;
    private JButton installedDetailsBtn;
    private JButton assumedDetailsBtn;
    private JTable selectedInstalledDetailsList;
    private JTable selectedAssumedDetailsList;
    private SimpleDatePicker serviceCompleteDate;
    private JTextField cost;

    private List<UsedDetail> usedDetailList;
    private List<BrokenDetail> brokenDetailList;

    public ServiceDialog(Service service, DialogType dialogType) {
        super(com.silverhaze.diamond.client.ui.UIHelper.getMainFrame(), "title", true);

        this.service = service;
        edit = (service != null);
        this.dialogType = dialogType;

        initView();

        if (dialogType == DialogType.VIEW || dialogType == DialogType.EDIT) {
            initWithData();
        }

        pack();
        setLocationRelativeTo(null);
    }

    private void initView() {
        setTitle("Добавление сервиса");

        if (edit) {
            setTitle("Редактировать сервис");
            add(initTopPanel(), BorderLayout.PAGE_START);
        }

        if (dialogType == DialogType.VIEW) {
            setTitle("Просмотр сервиса");
        }

        if ((dialogType == DialogType.VIEW || dialogType == DialogType.EDIT) && service.isServiceComplete()) {
            setTitle(getCaption() + "Редактирование завершенного сервиса");

            if (dialogType == DialogType.VIEW) {
                setTitle("Просмотр завершенного сервиса");
            }

            add(CommonUIHelper.createHorizontalBox(initMainPanel(), initServiceCompletedPanel()),
                    BorderLayout.CENTER);
        } else {
            add(initMainPanel(), BorderLayout.CENTER);
        }

        add(initButtonsPanel(), BorderLayout.PAGE_END);

        if (dialogType == DialogType.VIEW) {
            enableInput(false);
        }
    }

    private JPanel initButtonsPanel() {
        JPanel temp = new JPanel(new BorderLayout());

        temp.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        temp.add(CommonUIHelper.createHorizontalBox(10, "* - обязательные поля"), BorderLayout.LINE_START);
        temp.add(CommonUIHelper.createHorizontalBox(
                dialogType != DialogType.VIEW ?
                        new JButton(new AbstractAction(edit ? "Сохранить" : "Добавить") {
                            public void actionPerformed(ActionEvent e) {
                                okPressed();
                            }
                        }) : 0,
                new JButton(new AbstractAction(dialogType == DialogType.VIEW ? "Закрыть" : "Отмена") {
                    public void actionPerformed(ActionEvent e) {
                        cancelPressed();
                    }
                }),
                10
        ), BorderLayout.LINE_END);

        return temp;
    }

    private JPanel initServiceCompletedPanel() {
        JPanel panel = new JPanel(new SpringLayout());

        guarantyRadioButton = new JRadioButton("гарантия");
        payedRadioButton = new JRadioButton("оплачено");
        modernRadioButton = new JRadioButton("модернизация");
        refuseRadioButton = new JRadioButton("отказано");
        guarantyRadioButton.setSelected(true);

        CommonUIHelper.createButtonGroup(guarantyRadioButton,
                payedRadioButton,
                modernRadioButton,
                refuseRadioButton
        );

        selectedInstalledDetailsList = new CountedDetailTable();
        installedDetailsBtn = new JButton("Выбрать детали");

        selectedAssumedDetailsList = new CountedDetailTable();

        usedDetailList = new ArrayList<UsedDetail>();
        installedDetailsBtn = new JButton(new AbstractAction("Выбрать детали") {
            public void actionPerformed(ActionEvent e) {

                DetailSelectorDialog.selectDetails(new DialogConnector() {
                    public void objectSelected(Object o) {
                        if (o != null) {
                            usedDetailList = (java.util.List<UsedDetail>) o;
                            ((CountedDetailsTableModel) selectedInstalledDetailsList.getModel()).fillData(usedDetailList);
                        }
                    }
                }, ((CountedDetailsTableModel) selectedInstalledDetailsList.getModel()).getDataList(), UsedDetail.class);

                service.setUsedDetailes(new HashSet<UsedDetail>(usedDetailList));
            }
        });

        brokenDetailList = new ArrayList<BrokenDetail>();
        assumedDetailsBtn = new JButton(new AbstractAction("Выбрать детали") {
            public void actionPerformed(ActionEvent e) {
                DetailSelectorDialog.selectDetails(new DialogConnector() {
                    public void objectSelected(Object o) {
                        if (o != null) {
                            brokenDetailList = (java.util.List<BrokenDetail>) o;
                            ((CountedDetailsTableModel) selectedAssumedDetailsList.getModel()).fillData(brokenDetailList);
                        }
                    }
                }, ((CountedDetailsTableModel) selectedAssumedDetailsList.getModel()).getDataList(), BrokenDetail.class);

                service.setBrokenDetailes(new HashSet<BrokenDetail>(brokenDetailList));
            }
        });

        serviceCompleteDate = new SimpleDatePicker();
        cost = createTextField(10);

        final JScrollPane installedScrollPane = new JScrollPane(selectedInstalledDetailsList);
        installedScrollPane.setPreferredSize(new Dimension(200, 150));

        final JScrollPane assumedScrollPane = new JScrollPane(selectedAssumedDetailsList);
        assumedScrollPane.setPreferredSize(new Dimension(200, 150));

        CommonUIHelper.addToPanel(panel,
                "Тип сервиса:", CommonUIHelper.createHorizontalBox(guarantyRadioButton, 31, payedRadioButton),
                "", CommonUIHelper.createHorizontalBox(modernRadioButton, refuseRadioButton),
                "Установленные детали: ", installedScrollPane,
                "", installedDetailsBtn,
                "Принятые детали: ", assumedScrollPane,
                "", assumedDetailsBtn,
                "Дата: ", serviceCompleteDate,
                "Стоимость ремонта: ", cost
        );

        SpringUtilities.makeCompactGrid(panel, 8, 2, 10, 10, 10, 10);
        panel.setBorder(BorderFactory.createTitledBorder(" Завершение сервиса "));

        JPanel result = CommonUIHelper.packInPanel(panel);
        result.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0));

        add(result, BorderLayout.CENTER);

        setLocationRelativeTo(null);
        return result;
    }

    private JPanel initMainPanel() {
        diagRadioButton = new JRadioButton("дигностика");
        repairRadioButton = new JRadioButton("ремонт");
        repairRadioButton.setSelected(true);
        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(diagRadioButton);
        buttonGroup.add(repairRadioButton);

        initializeFields();
        dateOfProduce = new SimpleDatePicker();


        customerDefect = createTextArea(6, 10);
        customerDefect.setLineWrap(true);
        customerDefect.setWrapStyleWord(true);
        customerDefect.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        masterDefect = createTextArea(6, 10);
        masterDefect.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        masterDefect.setText("посмотрим");

        JPanel panel = new JPanel(new SpringLayout());

        customerSelectorBtn = new JButton(new AbstractAction("не выбран") {
            public void actionPerformed(ActionEvent e) {
                CustomerSelectorDialog.selectCustomer(new DialogConnector() {
                    public void objectSelected(Object o) {
                        selectedCustomer = (Customer) o;

                        long customerId = DAOLocator.getInstance().add(selectedCustomer);
                        selectedCustomer.setId(customerId);

                        if (selectedCustomer.isBOrganization()) {
                            customerSelectorBtn.setText(selectedCustomer.getOrganization());
                        } else {
                            customerSelectorBtn.setText(selectedCustomer.getSurname() + " " + selectedCustomer.getName());
                        }
                    }
                });
            }
        });

        CommonUIHelper.addToPanel(panel,
                "Тип: ", CommonUIHelper.createHorizontalBox(diagRadioButton, repairRadioButton),
                "Принятая техника*: ", techName,
                "Изделие (модель)*: ", modelName,
                "Тех. название модели: ", techModelName,
                "Состояние пломбы: ", stampState,
                "Серийный номер*: ", serialNumber,
                "Дата покупки: ", getDateOfProduceComponent(),
                "Гарантийный номер*: ", guarantyNumber,
                "Целостность*: ", completeness,
                "Покупатель*: ", getCustomerComponent(),
                "Неисправность*: ", new JScrollPane(customerDefect),
                "Комментарий мастера*: ", new JScrollPane(masterDefect)
        );

        SpringUtilities.makeCompactGrid(panel, 12, 2, 10, 5, 10, 10);
        panel.setBorder(BorderFactory.createTitledBorder(" Детали сервиса "));

        JPanel result = CommonUIHelper.packInPanel(panel);
        result.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0));

        return result;
    }

    private void initializeFields() {

        Set<String> techNames = new HashSet<String>();
        Set<String> modelNames = new HashSet<String>();
        Set<String> techModelNames = new HashSet<String>();
        Set<String> stampStates = new HashSet<String>();
        Set<String> completnesses = new HashSet<String>();

        final List<ObjectEntity> entities = DAOLocator.getInstance().getServices();
        for (ObjectEntity oe : entities) {
            Service service = (Service) oe;

            techNames.add(service.getTechNames());
            modelNames.add(service.getModelName());
            techModelNames.add(service.getTechModelName());
            stampStates.add(service.getStampState());
            completnesses.add(service.getCompleteness());
        }

        techName = new StringAutoCompleteComboBox(packInSortedList(techNames));
        modelName = new StringAutoCompleteComboBox(packInSortedList(modelNames));
        techModelName = new StringAutoCompleteComboBox(packInSortedList(techModelNames));
        stampState = new StringAutoCompleteComboBox(packInSortedList(stampStates));
        completeness = new StringAutoCompleteComboBox(packInSortedList(completnesses));

        serialNumber = createTextField(FIELD_SIZE);
        guarantyNumber = createTextField(FIELD_SIZE);
    }

    private static List<String> packInSortedList(Set<String> set) {
        List<String> list = new ArrayList<String>(set);
        Collections.sort(list);
        return list;
    }

    private JComponent getDateOfProduceComponent() {
        if (dialogType == DialogType.VIEW) {
            return new JLabel("<html><b>" + AuroraConstants.DATE_TIME_FORMAT.format(dateOfProduce.getDate()) + "</b></html>");
        } else {
            return dateOfProduce;
        }
    }

    private JComponent getCustomerComponent() {
        if (dialogType == DialogType.VIEW) {
            return new JLabel("<html><b>" + service.getOwner().getExtendedName() + "</b><html>");
        } else {
            return customerSelectorBtn;
        }
    }

    private JPanel initTopPanel() {
        JPanel panel = new JPanel(new BorderLayout());

        JLabel statusLabel = new JLabel("<html><b>СТАТУС: " + (service.isServiceComplete() ?
                "<font color=\"green\">ЗАВЕРШЕН</font>" : "<font color=\"red\">В РЕМОНТЕ</font>"));

        panel.add(statusLabel, BorderLayout.LINE_END);
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 15));

        return panel;
    }

    private void initWithData() {
        if (service.isRepair()) {
            repairRadioButton.setSelected(true);
        } else {
            diagRadioButton.setSelected(true);
        }

        techName.setText(service.getTechNames());
        modelName.setText(service.getModelName());
        techModelName.setText(service.getTechModelName());
        serialNumber.setText(service.getSerialNumber());
        dateOfProduce.setDate(service.getDateProduce());
        stampState.setText(service.getStampState());
        guarantyNumber.setText(service.getGuarantyId());
        completeness.setText(service.getCompleteness());
        customerDefect.setText(service.getOwnerDefect());
        masterDefect.setText(service.getMasterDefect());

        Customer owner = service.getOwner();
        if (owner.isBOrganization()) {
            customerSelectorBtn.setText(owner.getOrganization());
        } else {
            customerSelectorBtn.setText(owner.getSurname() + " " + owner.getName());
        }

        selectedCustomer = owner;

        if (service.isServiceComplete()) {
            String serviceType = service.getServiceType();
            if (serviceType != null) {
                if (serviceType.equals(AuroraConstants.GUARANTY)) {
                    guarantyRadioButton.setSelected(true);
                } else if (serviceType.equals(AuroraConstants.PAYED)) {
                    payedRadioButton.setSelected(true);
                } else if (serviceType.equals(AuroraConstants.MODERNIZATION)) {
                    modernRadioButton.setSelected(true);
                } else if (serviceType.equals(AuroraConstants.REFUSE)) {
                    refuseRadioButton.setSelected(true);
                }
            }

            serviceCompleteDate.setDate(service.getServiceCompleteDate());
            selectedInstalledDetailsList.setModel(new CountedDetailsTableModel(service.getUsedDetailes()));
            selectedAssumedDetailsList.setModel(new CountedDetailsTableModel(service.getBrokenDetailes()));
            cost.setText("" + service.getCost());
        }
    }

    protected void okPressed() {
        Service service = checkField();

        if (service != null) {
            if (service.getOwnerDefect().length() > 255) {
                JOptionPane.showMessageDialog(null, "Неисправность со слов заказчика должна быть короче 255 символов", "Ошибка", JOptionPane.ERROR_MESSAGE);
                return;
            }

            if (service.getMasterDefect().length() > 255) {
                JOptionPane.showMessageDialog(null, "Комментарий приемщика должен быть короче 255 символов", "Ошибка", JOptionPane.ERROR_MESSAGE);
                return;
            }

            if (edit) {
                DAOLocator.getInstance().update(service);
            } else {
                DAOLocator.getInstance().add(service);
            }

            dispose();
        } else {
            Dialogs.showErrorDialog(this, "Пожалуйста заполните все поля корректно");
        }
    }

    private Service checkField() {
        Service localService = edit ? service : new Service();

        String techNamesStr = techName.getText().trim();
        String modelNameStr = modelName.getText().trim();
        String techModelNameStr = techModelName.getText().trim();
        String serialNumStr = serialNumber.getText().trim();
        Date dateProduce = dateOfProduce.getDate();
        String stampStateStr = stampState.getText().trim();
        String guarantyNumStr = guarantyNumber.getText().trim();
        String completenessStr = completeness.getText().trim();
        String customerDefectStr = customerDefect.getText().trim();
        String masterDefectStr = masterDefect.getText().trim();

        if (techNamesStr.equals("") || modelNameStr.equals("") ||
                serialNumStr.equals("") || guarantyNumStr.equals("") ||
                completenessStr.equals("") || customerDefectStr.equals("") ||
                masterDefectStr.equals("") || selectedCustomer == null) {
            return null;
        }

        if (service != null && service.isServiceComplete()) {
            defineServiceType(service);

            String costStr = cost.getText().trim();
            if (costStr.equals("")) {
                return null;
            }

            try {
                localService.setCost(Double.parseDouble(costStr));
            } catch (NumberFormatException nfe) {
                return null;
            }
        }

        localService.setRepair(!diagRadioButton.isSelected());
        localService.setTechNames(techNamesStr);
        localService.setModelName(modelNameStr);
        localService.setTechModelName(techModelNameStr);
        localService.setSerialNumber(serialNumStr);
        localService.setDateProduce(dateProduce);
        localService.setStampState(stampStateStr);
        localService.setGuarantyId(guarantyNumStr);
        localService.setCompleteness(completenessStr);
        localService.setOwnerDefect(customerDefectStr);
        localService.setMasterDefect(masterDefectStr);
        localService.setDateService(new Date());

        localService.setOwner(selectedCustomer);
        localService.setSystemUser(SettingsStorage.getUserSettings().getCurrentUser());

        return localService;
    }

    private void defineServiceType(Service service) {
        String serviceType = "";

        if (guarantyRadioButton.isSelected()) {
            serviceType = AuroraConstants.GUARANTY;
        } else if (payedRadioButton.isSelected()) {
            serviceType = AuroraConstants.PAYED;
        } else if (refuseRadioButton.isSelected()) {
            serviceType = AuroraConstants.REFUSE;
        } else if (modernRadioButton.isSelected()) {
            serviceType = AuroraConstants.MODERNIZATION;
        }

        service.setServiceType(serviceType);
    }

    protected void cancelPressed() {
        dispose();
    }

    public static void editService(Service service) {
        ServiceDialog serviceDialog = new ServiceDialog(service, DialogType.EDIT);
        serviceDialog.setVisible(true);
    }

    public static void createService() {
        ServiceDialog serviceDialog = new ServiceDialog(null, DialogType.CREATE);
        serviceDialog.setVisible(true);
    }

    public static void createClone(Service service) {
        ServiceDialog serviceDialog = new ServiceDialog(null, DialogType.CREATE);
        serviceDialog.initializeFieldsWith(service);
        serviceDialog.setVisible(true);
    }

    private void initializeFieldsWith(Service service) {
        techName.setText(service.getTechNames());
        modelName.setText(service.getModelName());
        techModelName.setText(service.getTechModelName());
        serialNumber.setText(service.getSerialNumber());
        dateOfProduce.setDate(service.getDateProduce());
        stampState.setText(service.getStampState());
        guarantyNumber.setText(service.getGuarantyId());
        completeness.setText(service.getCompleteness());
        customerDefect.setText(service.getOwnerDefect());
        masterDefect.setText(service.getMasterDefect());

        selectedCustomer = service.getOwner();
        if (selectedCustomer.isBOrganization()) {
            customerSelectorBtn.setText(selectedCustomer.getOrganization());
        } else {
            customerSelectorBtn.setText(selectedCustomer.getSurname() + " " + selectedCustomer.getName());
        }
    }

    public void enableInput(boolean editable) {
        super.enableInput(false);

        customerSelectorBtn.setEnabled(editable);
        diagRadioButton.setEnabled(editable);
        repairRadioButton.setEnabled(editable);
        dateOfProduce.setEnabled(editable);

        if (service.isServiceComplete()) {
            installedDetailsBtn.setEnabled(editable);
            assumedDetailsBtn.setEnabled(editable);
            guarantyRadioButton.setEnabled(editable);
            payedRadioButton.setEnabled(editable);
            modernRadioButton.setEnabled(editable);
            refuseRadioButton.setEnabled(editable);
            serviceCompleteDate.setEnabled(editable);
            cost.setEditable(editable);
        }
    }
}

